package com.nullpointer.xchatfinal;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import net.simonvt.menudrawer.MenuDrawer;
import net.simonvt.menudrawer.MenuDrawer.OnDrawerStateChangeListener;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Vibrator;
import android.provider.Settings;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.LocalBroadcastManager;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.LayoutParams;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.facebook.AppEventsLogger;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.InterstitialAd;
import com.nullpointer.xchatfinal.adapter.ChatAdapter;
import com.nullpointer.xchatfinal.adapter.EmoticonAdapter;
import com.nullpointer.xchatfinal.database.MessagesDataManager;
import com.nullpointer.xchatfinal.fragment.ChooseFriendDialogFragment;
import com.nullpointer.xchatfinal.fragment.ChooseFriendDialogFragment.OnChooseFriendDialogFragment;
import com.nullpointer.xchatfinal.fragment.ChooseImageDialogFragment;
import com.nullpointer.xchatfinal.fragment.ChooseImageDialogFragment.OnChooseImageDialogFragment;
import com.nullpointer.xchatfinal.fragment.EditProfileDialogFragment;
import com.nullpointer.xchatfinal.fragment.FindFriendResultsFragment;
import com.nullpointer.xchatfinal.fragment.FindFriendSettingDialogFragment;
import com.nullpointer.xchatfinal.fragment.FriendsFragment;
import com.nullpointer.xchatfinal.fragment.GroupsFragment;
import com.nullpointer.xchatfinal.fragment.LogoutConfirmDialogFragment;
import com.nullpointer.xchatfinal.fragment.LogoutConfirmDialogFragment.OnLogoutDialogListener;
import com.nullpointer.xchatfinal.fragment.MessageFragment;
import com.nullpointer.xchatfinal.fragment.NearbyFragment;
import com.nullpointer.xchatfinal.fragment.SayHiDialogFragment;
import com.nullpointer.xchatfinal.fragment.SearchFragment;
import com.nullpointer.xchatfinal.fragment.SettingDialogFragment;
import com.nullpointer.xchatfinal.fragment.SettingDialogFragment.OnSettingDialogFragment;
import com.nullpointer.xchatfinal.fragment.SuggestedFriendsFragment;
import com.nullpointer.xchatfinal.fragment.ViewProfileFragment;
import com.nullpointer.xchatfinal.object.ChatType;
import com.nullpointer.xchatfinal.object.GroupChat;
import com.nullpointer.xchatfinal.object.GroupMessageContent;
import com.nullpointer.xchatfinal.object.MainDisplayState;
import com.nullpointer.xchatfinal.object.MenuItemType;
import com.nullpointer.xchatfinal.object.MessageContent;
import com.nullpointer.xchatfinal.object.MessageContent.MsgType;
import com.nullpointer.xchatfinal.object.DetailedMessage;
import com.nullpointer.xchatfinal.object.HistoryMessage;
import com.nullpointer.xchatfinal.object.MessageState;
import com.nullpointer.xchatfinal.object.OnJoinRoomListener;
import com.nullpointer.xchatfinal.object.OnSendGroupMessageListener;
import com.nullpointer.xchatfinal.object.OnSendPrivateMessageListener;
import com.nullpointer.xchatfinal.object.PrivateMessageContent;
import com.nullpointer.xchatfinal.object.SaveStateConfig;
import com.nullpointer.xchatfinal.object.SelectFriend;
import com.nullpointer.xchatfinal.object.TargetChat;
import com.nullpointer.xchatfinal.object.User;
import com.nullpointer.xchatfinal.object.UserInfo;
import com.nullpointer.xchatfinal.object.UserInfo.GenderType;
import com.nullpointer.xchatfinal.service.ChatService;
import com.nullpointer.xchatfinal.utils.AppNotificationManager;
import com.nullpointer.xchatfinal.utils.Common;
import com.nullpointer.xchatfinal.utils.DataManager;
import com.nullpointer.xchatfinal.utils.Emoticons;
import com.nullpointer.xchatfinal.utils.Error;
import com.nullpointer.xchatfinal.utils.Error.ErrorCode;
import com.nullpointer.xchatfinal.utils.InfoText;
import com.nullpointer.xchatfinal.utils.KiraGameLog;
import com.nullpointer.xchatfinal.utils.TextFilter;
import com.nullpointer.xchatfinal.utils.Utils;
import com.quickblox.chat.QBChatService;
import com.quickblox.chat.QBGroupChatManager;
import com.quickblox.chat.model.QBDialog;
import com.quickblox.content.QBContent;
import com.quickblox.content.model.QBFile;
import com.quickblox.core.Consts;
import com.quickblox.core.QBEntityCallbackImpl;
import com.quickblox.core.request.QBPagedRequestBuilder;
import com.quickblox.core.request.QBRequestUpdateBuilder;
import com.quickblox.users.QBUsers;
import com.quickblox.users.model.QBUser;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import com.sothree.slidinguppanel.SlidingUpPanelLayout.PanelSlideListener;

public class MainActivity extends SherlockFragmentActivity {

	// FLOWS: SETUP SERVER ->JOIN ROOM
	// -> CHECK PROFILE AND UPDATE
	// -> LOAD SUGGESTED USER
	//
	//
	// IN ROOM
	// Layout
	private MenuDrawer mDrawerMenu;
	private ActionBar mActionBar;

	private ListView lvChat;
	private EditText etMessage;
	private ImageButton btSend;
	private GridView gvEmoticons;
	private ImageButton btEmoticon;
	private ImageButton btImage;
	private SlidingUpPanelLayout slidingLayout;
	private Button btFindchat;
	private ImageButton btFindFriendSetting;
	private TextView tvTyping;
	private TextView tvMessageTip;

	private static final long TIME_SHOW_ADS = 1000 * 45;

	// SNACK BAR
	private LinearLayout llNotice;
	private ProgressBar pbLoading;
	private TextView tvNotice;
	private View vSplit;
	private TextView tvAction;
	private Animation animationShow;
	private Animation animationHide;
	private Animation animationRotate;

	// Actionbar
	private RelativeLayout rlMenu;
	private ImageButton ibMenu;
	private TextView tvNumMessage;
	private LinearLayout llUserInfo;
	private LinearLayout llTitle;
	private TextView tvName;
	private TextView tvStatus;
	private TextView tvTitle;
	private ImageButton ibRefresh;
	private ImageButton ibVideoCall;
	private ImageButton ibAction;

	// MENU FRAGMENT
	private LinearLayout llMessage;
	private TextView tvMessageNum;
	private LinearLayout llFriend;
	private LinearLayout llNearby;
	private LinearLayout llSuggestedFriend;
	private LinearLayout llPublicGroup;
	private ImageButton ibLogout;
	private ImageButton ibEditProfile;
	private Button btSetting;
	private LinearLayout llSearch;

	// CHAT IN ROOM
	private List<MessageContent> messagesData = new ArrayList<MessageContent>();
	private ChatAdapter chatAdapter;

	private Set<Integer> findUserIDInList = new HashSet<>();
	// private Set<Integer> chatedUserIDs = new HashSet<>();

	private boolean isTyping = false;
	// COMMON
	private MainDisplayState mDisplayState = MainDisplayState.MAIN;
	private Vibrator vibrator;

	private boolean isFindingChat = false;

	private Fragment mContent;
	private FragmentManager fm;
	private MenuItemType currentMenuItem;

	// INFO
	private LinearLayout llInfo;
	private ProgressBar pbInfo;
	private TextView tvInfo;

	// Saved Instance State
	private final String SAVE_STATE_CONFIG = "SAVE_STATE_CONFIG";

	private LinearLayout llAdViewMain;
	private LinearLayout llAdViewChat;
	private AdView adView;
	private InterstitialAd interstitial;
	private CountDownTimer mCountDownTimer;
	boolean isLoadDataAgain = true;

	private int messageNum = 0;
	private View loadmoreView;

	private boolean isLoadDone = true;
	private boolean canLoadMore = false;
	private int page = 0;

	private User currentUser;

	private int tryToLoadBanerAdsCount = 0;
	private int tryToLoadBigAdsCount = 0;

	private String userIdNotify = null;
	private String userNameNotify = null;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		KiraGameLog.d("-------- onCreate --------");
		currentUser = DataManager.getInstance(this).getCurrentUser();
		if (currentUser == null || currentUser.getUserID() == null) {
			KiraGameLog.d("currentUser null");
			DataManager.getInstance(this).setIsLogout(true);
			startSplashActivity(false);
			return;
		}
		settingActionbar();
		settingSlidingMenu();
		findViews();
		init(savedInstanceState);
		setEvent();

	}

	private void checkViewNotify() {
		if (userIdNotify == null || userNameNotify == null) {
			Bundle extras = getIntent().getExtras();
			if (extras != null) {
				userIdNotify = extras.getString(Common.ExtraKey.USER_ID, null);
				userNameNotify = extras.getString(Common.ExtraKey.USER_NAME,
						null);
				KiraGameLog.d("not onNewIntent " + userIdNotify + "-"
						+ userNameNotify);
				getIntent().removeExtra(Common.ExtraKey.USER_ID);
				getIntent().removeExtra(Common.ExtraKey.USER_NAME);
			} else {
				KiraGameLog.d("not onNewIntent null");
			}
		}

		if (userIdNotify != null && userNameNotify != null) {
			TargetChat targetChat = new TargetChat(ChatType.CHAT_PRIVATE,
					userIdNotify, userNameNotify);
			showChat(targetChat);
			userIdNotify = null;
			userNameNotify = null;
		}
	}

	@Override
	protected void onNewIntent(Intent intent) {
		KiraGameLog.d("-------------onNewIntent------------");
		Bundle extras = intent.getExtras();
		if (extras != null) {
			userIdNotify = extras.getString(Common.ExtraKey.USER_ID, null);
			userNameNotify = extras.getString(Common.ExtraKey.USER_NAME, null);
			KiraGameLog.d("onNewIntent " + userIdNotify + "-" + userNameNotify);
		}
		super.onNewIntent(intent);
	}

	@Override
	protected void onSaveInstanceState(Bundle savedInstanceState) {
		super.onSaveInstanceState(savedInstanceState);
		SaveStateConfig config = new SaveStateConfig();
		config.setmDisplayState(mDisplayState);
		config.setMenuItemType(currentMenuItem);
		savedInstanceState.putString(SAVE_STATE_CONFIG, config.toJson());
		KiraGameLog.d("onSaveInstanceState SAVE_STATE_CONFIG: "
				+ config.toJson());
	}

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode,
			Intent itent) {
		super.onActivityResult(requestCode, resultCode, itent);
		switch (requestCode) {
		case Common.RequestCode.CHAT_IMAGE:
			if (resultCode == RESULT_CANCELED) {
				return;
			}
			String path = itent.getStringExtra(ProcessImage.LOCAL_URL);
			sendMessageImagePrivate(path);
			break;
		case Common.RequestCode.SPLASH_ACTIVITY:
			doWhenChatServiceReady();
			break;
		}
	}

	@Override
	public void onBackPressed() {
		if (mDrawerMenu.isMenuVisible()) {
			mDrawerMenu.toggleMenu();
		} else if (gvEmoticons.getVisibility() == View.VISIBLE) {
			gvEmoticons.setVisibility(View.GONE);
		} else if (slidingLayout != null && slidingLayout.isPanelExpanded()
				|| slidingLayout.isPanelAnchored()) {
			hideChat();
		} else {
			super.onBackPressed();
		}
	}

	@Override
	protected void onDestroy() {
		KiraGameLog.d("--------- onDestroy ---------");
		DataManager.getInstance(this).setIsAppPause(true);
		DataManager.getInstance(this).setCurrentTargetChat(null);
		try {
			LocalBroadcastManager.getInstance(this).unregisterReceiver(
					changeUIReceiver);

			llAdViewChat.removeAllViews();
			llAdViewMain.removeAllViews();
			if (adView != null) {
				adView.removeAllViews();
				adView.destroy();
			}

			// if (mAdViewChat != null) {
			// mAdViewChat.destroy();
			// }
		} catch (Exception e) {
			e.printStackTrace();
		}

		super.onDestroy();
	}

	@Override
	protected void onStop() {
		KiraGameLog.d("--------- onStop ---------");
		super.onStop();
	}

	@Override
	protected void onPause() {
		KiraGameLog.d("--------- onPause ---------");

		sendChatStopTyping();
		DataManager.getInstance(this).setIsAppPause(true);
		if (adView != null) {
			adView.pause();
		}

		// if (mAdViewChat != null) {
		// mAdViewChat.pause();
		// }

		if (mCountDownTimer != null) {
			mCountDownTimer.cancel();
		}
		super.onPause();
		AppEventsLogger.deactivateApp(this);
	}

	@Override
	protected void onResume() {
		super.onResume();
		KiraGameLog.d("--------- onResume ---------");
		isLoadDataAgain = false;
		checkAccoutnAndChatServiceAlive();

		if (adView != null) {
			adView.resume();
		}

		// if (mAdViewChat != null) {
		// mAdViewChat.resume();
		// }
		AppEventsLogger.activateApp(this);
	}

	@Override
	public void onDetachedFromWindow() {
		super.onDetachedFromWindow();
		KiraGameLog.d("--------- onDetachedFromWindow ---------");
	}

	private void settingSlidingMenu() {
		mDrawerMenu = MenuDrawer.attach(this);
		mDrawerMenu.setContentView(R.layout.activity_main);
		mDrawerMenu.setMenuView(getMenuView());
		mDrawerMenu.setDropShadowColor(Color.parseColor("#ff8800"));
		mDrawerMenu.setDropShadowSize(1);
		int width = 2 * (getResources().getDisplayMetrics().widthPixels / 3);
		mDrawerMenu.setMenuSize(width);
	}

	private void settingActionbar() {
		View customView = getActionbarView();
		LayoutParams layout = new LayoutParams(LayoutParams.MATCH_PARENT,
				LayoutParams.MATCH_PARENT);
		mActionBar = getSupportActionBar();
		mActionBar.setCustomView(customView, layout);
		// mActionBar.hide();
		mActionBar.setDisplayShowHomeEnabled(false);
		mActionBar.setDisplayHomeAsUpEnabled(false);
		mActionBar.setDisplayShowCustomEnabled(true);
		mActionBar.setDisplayShowTitleEnabled(false);
		// mActionBar.setCustomView(getActionbarView());
		mActionBar.show();
	}

	private View getActionbarView() {
		View view = getLayoutInflater().inflate(R.layout.actionbar_main, null);
		rlMenu = (RelativeLayout) view.findViewById(R.id.rl_menu);
		ibMenu = (ImageButton) view.findViewById(R.id.ib_menu);
		tvNumMessage = (TextView) view.findViewById(R.id.tv_num_message);
		llUserInfo = (LinearLayout) view.findViewById(R.id.ll_user_info);
		llTitle = (LinearLayout) view.findViewById(R.id.ll_title);
		tvName = (TextView) view.findViewById(R.id.tv_name);
		tvStatus = (TextView) view.findViewById(R.id.tv_status);
		tvTitle = (TextView) view.findViewById(R.id.tv_title);
		ibRefresh = (ImageButton) view.findViewById(R.id.ib_refresh);
		ibVideoCall = (ImageButton) view.findViewById(R.id.ib_video_call);
		ibAction = (ImageButton) view.findViewById(R.id.ib_action);
		return view;
	}

	private void findViews() {
		tvNotice = (TextView) findViewById(R.id.tv_notice);
		lvChat = (ListView) findViewById(R.id.lv_chat);
		etMessage = (EditText) findViewById(R.id.et_message);
		btSend = (ImageButton) findViewById(R.id.bt_send);
		slidingLayout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout);

		gvEmoticons = (GridView) findViewById(R.id.gv_emoticons);
		btEmoticon = (ImageButton) findViewById(R.id.bt_emoticon);
		btImage = (ImageButton) findViewById(R.id.bt_image);
		llNotice = (LinearLayout) findViewById(R.id.ll_notice);
		pbLoading = (ProgressBar) findViewById(R.id.pbLoading);
		tvNotice = (TextView) findViewById(R.id.tv_notice);
		vSplit = (View) findViewById(R.id.v_split);
		tvAction = (TextView) findViewById(R.id.tv_action);
		btFindchat = (Button) findViewById(R.id.bt_findchat);
		llAdViewMain = (LinearLayout) findViewById(R.id.llAdViewMain);
		llAdViewChat = (LinearLayout) findViewById(R.id.llAdViewChat);
		tvTyping = (TextView) findViewById(R.id.tv_typing);
		tvMessageTip = (TextView) findViewById(R.id.tv_message_tip);
		btFindFriendSetting = (ImageButton) findViewById(R.id.bt_find_friend_setting);

		llInfo = (LinearLayout) findViewById(R.id.ll_info);
		pbInfo = (ProgressBar) findViewById(R.id.pb_loading);
		tvInfo = (TextView) findViewById(R.id.tv_info);

		loadmoreView = LayoutInflater.from(this).inflate(
				R.layout.view_item_load_more, null);
	}

	private void init(Bundle savedInstanceState) {
		isLoadDataAgain = true;
		animationRotate = AnimationUtils.loadAnimation(this, R.anim.rotate);
		animationShow = AnimationUtils.loadAnimation(this,
				R.anim.snackbar_show_animation);
		animationHide = AnimationUtils.loadAnimation(this,
				R.anim.snackbar_hide_animation);
		vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
		// Default display chat room
		lvChat.addHeaderView(loadmoreView);
		loadmoreView.setVisibility(View.GONE);

		chatAdapter = new ChatAdapter(this, messagesData);
		lvChat.setAdapter(chatAdapter);
		lvChat.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
		lvChat.setStackFromBottom(true);
		btSend.setEnabled(false);

		refreshMessageNum();

		EmoticonAdapter emoticonAdapter = new EmoticonAdapter(this);
		gvEmoticons.setAdapter(emoticonAdapter);

		slidingLayout.setDragView(new View(this));

		IntentFilter filter = new IntentFilter(ChatService.BROADCAST_NAME_MAIN);
		LocalBroadcastManager.getInstance(this).registerReceiver(
				changeUIReceiver, filter);
		checkAccoutnAndChatServiceAlive();

		fm = getSupportFragmentManager();

		if (savedInstanceState != null) {
			SaveStateConfig config = SaveStateConfig
					.fromJsonToSaveStateConfig(savedInstanceState
							.getString(SAVE_STATE_CONFIG));
			KiraGameLog.d("onRestoreInstanceState SAVE_STATE_CONFIG: "
					+ config.toJson());
			mDisplayState = config.getmDisplayState();
			currentMenuItem = config.getMenuItemType();

			if (mDisplayState != MainDisplayState.MAIN) {
				showChat(DataManager.getInstance(this).getCurrentTargetChat());
			} else {
				hideChat();
			}
			mContent = getFragment(currentMenuItem);
		}

		// get fragment default
		if (mContent == null) {
			currentMenuItem = MenuItemType.MESSAGE;
			mContent = getFragment(currentMenuItem);
		}
		switchContent(mContent);
		ibRefresh.setEnabled(false);
		// changeActionBarState(mDisplayState);
		AppNotificationManager.getInstance(this).setUp(72,
				"Someone want to chat with you!");
	}

	private void checkAccoutnAndChatServiceAlive() {
		KiraGameLog.d("checkAccoutnAndChatServiceAlive");

		if (DataManager.getInstance(this).isLogout()) {
			KiraGameLog.d("DataManager.getInstance(this).isLogout()");
			startSplashActivity(false);
		} else if ((ChatService.getInstance() == null)) {
			KiraGameLog.d("ChatService.getInstance() == null");
			startSplashActivity(false);
		} else if (((ChatService.getInstance() != null) && !ChatService
				.getInstance().isLogin())) {
			KiraGameLog.d("!ChatService.getInstance().isLogin()");
			startSplashActivity(true);
			// finish();
		} else {
			doWhenChatServiceReady();
		}
	}

	private void doWhenChatServiceReady() {
		KiraGameLog.d("doWhenChatServiceReady");
		DataManager.getInstance(this).setIsAppPause(false);
		lvChat.setSelection(messagesData.size() - 1);
		checkViewNotify();
		if (!isLoadDataAgain) {
			return;
		}
		KiraGameLog.d("Reload data when ChatServiceReady");
		if (!DataManager.getInstance(MainActivity.this).isShowPost()) {
			showSayHi();
			DataManager.getInstance(MainActivity.this).setIsShowPost(true);
		}
		initAds();
	}

	private void startSplashActivity(boolean isKeepMainUI) {
		if (isKeepMainUI) {
			Intent intent = new Intent(this, SplashActivity.class);
			intent.putExtra("isKeepMainUI", true);
			startActivityForResult(intent, Common.RequestCode.SPLASH_ACTIVITY);
		} else {
			Intent intent = new Intent(this, SplashActivity.class);
			startActivity(intent);
			finish();
		}

	}

	private void initAds() {
		adView = new AdView(this);
		adView.setAdSize(AdSize.SMART_BANNER);
		adView.setAdUnitId(getResources().getString(R.string.banner_ad_unit_id));

		final AdRequest adRequest = new AdRequest.Builder().addTestDevice(
				"CD3CF46DD6F23B701659BBF61B94EA51").build();

		// Start loading the ad in the background.
		adView.loadAd(adRequest);
		// mAdViewChat.loadAd(adRequest);

		adView.setAdListener(new AdListener() {
			@Override
			public void onAdLoaded() {
				KiraGameLog.d("adview onAdLoaded");
				adView.setVisibility(View.VISIBLE);
				super.onAdLoaded();
			}

			@Override
			public void onAdFailedToLoad(int errorCode) {
				KiraGameLog.d("adview onAdFailedToLoad");
				adView.setVisibility(View.GONE);
				if (tryToLoadBanerAdsCount < 3) {
					KiraGameLog.d("adview reload ads");
					adView.loadAd(adRequest);
					tryToLoadBanerAdsCount++;
				}
				super.onAdFailedToLoad(errorCode);
			}

			@Override
			public void onAdOpened() {
				KiraGameLog.d("adview onAdOpened");
				adView.loadAd(adRequest);
				super.onAdOpened();
			}
		});

		// add to view
		changeAdViewLayout();

		// Create the interstitial.
		interstitial = new InterstitialAd(this);
		interstitial.setAdUnitId(getResources().getString(
				R.string.interstitial_id));

		// Create ad request.
		final AdRequest interstitialAdRequest = new AdRequest.Builder()
				.addTestDevice("CD3CF46DD6F23B701659BBF61B94EA51").build();

		// Begin loading your interstitial.
		interstitial.loadAd(interstitialAdRequest);

		interstitial.setAdListener(new AdListener() {
			@Override
			public void onAdFailedToLoad(int errorCode) {
				KiraGameLog.d("interstitial onAdFailedToLoad");
				if (tryToLoadBigAdsCount < 3) {
					KiraGameLog.d("interstitial reload ads");
					interstitial.loadAd(interstitialAdRequest);
					tryToLoadBigAdsCount++;
				}
				super.onAdFailedToLoad(errorCode);
			}

			@Override
			public void onAdLoaded() {
				// TODO Auto-generated method stub
				KiraGameLog.d("interstitial onAdLoaded");
				super.onAdLoaded();
			}

			@Override
			public void onAdClosed() {
				KiraGameLog.d("interstitial onAdClosed");
				AdRequest adRequest = new AdRequest.Builder().addTestDevice(
						AdRequest.DEVICE_ID_EMULATOR).build();
				interstitial.loadAd(adRequest);
			}
		});
	}

	private void changeAdViewLayout() {
		if (adView == null) {
			return;
		}
		llAdViewChat.removeAllViews();
		llAdViewMain.removeAllViews();
		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
				LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
		if (mDisplayState == MainDisplayState.MAIN) {
			llAdViewMain.addView(adView, params);
		} else {
			llAdViewChat.addView(adView, params);
		}

	}

	// Invoke displayInterstitial() when you are ready to display an
	// interstitial.
	public void displayInterstitial() {
		if (interstitial != null) {
			if (interstitial.isLoaded()
					&& DataManager.getInstance(this).getCurrentTargetChat() == null) {
				interstitial.show();
			}
		} else {
			KiraGameLog.d("interstitial null");
		}

		if (mCountDownTimer != null) {
			mCountDownTimer.cancel();
		}
	}

	private void initAdsTimer() {
		if (mCountDownTimer != null) {
			mCountDownTimer.cancel();
		}
		mCountDownTimer = new CountDownTimer(TIME_SHOW_ADS, 1000) {
			@Override
			public void onTick(long millisUnitFinished) {
				KiraGameLog.d("time to show ads " + millisUnitFinished);
			}

			@Override
			public void onFinish() {
				displayInterstitial();
			}
		}.start();
	}

	public void showInfo(String messgae, boolean isShowProgessbar) {
		llInfo.setVisibility(View.VISIBLE);
		tvInfo.setText(messgae);
		if (isShowProgessbar) {
			pbInfo.setVisibility(View.VISIBLE);
		} else {
			pbInfo.setVisibility(View.GONE);
		}
	}

	public void hideInfo() {
		llInfo.setVisibility(View.GONE);
	}

	private void changeActionBarState() {
		tvStatus.setVisibility(View.GONE);
		if (mDisplayState == MainDisplayState.MAIN) {
			ibRefresh.setVisibility(View.VISIBLE);
			ibVideoCall.setVisibility(View.GONE);
			llUserInfo.setVisibility(View.GONE);
			llTitle.setVisibility(View.VISIBLE);
			setMainTitle();
		} else if (mDisplayState == MainDisplayState.CHAT_PRIVATE) {
			ibRefresh.setVisibility(View.GONE);
			ibVideoCall.setVisibility(View.GONE);
			llUserInfo.setVisibility(View.VISIBLE);
			llTitle.setVisibility(View.GONE);
		} else if (mDisplayState == MainDisplayState.CHAT_GROUP) {
			ibRefresh.setVisibility(View.GONE);
			ibVideoCall.setVisibility(View.GONE);
			llUserInfo.setVisibility(View.VISIBLE);
			llTitle.setVisibility(View.GONE);
		}
		changeActionButtonState();
	}

	private void changeActionButtonState() {
		if (mDisplayState == MainDisplayState.MAIN) {
			switch (currentMenuItem) {
			case MESSAGE:
				ibAction.setImageResource(R.drawable.ic_action_new_message);
				break;
			case FRIEND:
				ibAction.setImageResource(R.drawable.ic_action_person);
				break;
			case NEARBY:
				ibAction.setImageResource(R.drawable.ic_action_person);
				break;
			case SUGGESTED_FRIEND:
				ibAction.setImageResource(R.drawable.ic_action_person);
				break;
			case PUBLIC_GROUP:
				ibAction.setImageResource(R.drawable.ic_social_group_add);
				break;
			case SEARCH:
				ibAction.setImageResource(R.drawable.ic_action_person);
				break;

			default:
				ibAction.setImageResource(R.drawable.ic_action_person);
				break;
			}
		} else if (mDisplayState == MainDisplayState.CHAT_PRIVATE) {
			ibAction.setImageResource(R.drawable.ic_action_menu_option);
		} else if (mDisplayState == MainDisplayState.CHAT_GROUP) {
			ibAction.setImageResource(R.drawable.ic_action_menu_option);
		}
	}

	private void setMainTitle() {
		switch (currentMenuItem) {
		case MESSAGE:
			tvTitle.setText("Messages");
			break;
		case FRIEND:
			tvTitle.setText("Friends");
			break;
		case NEARBY:
			tvTitle.setText("Nearby");
			break;
		case SUGGESTED_FRIEND:
			tvTitle.setText("Online Users");
			break;
		case PUBLIC_GROUP:
			tvTitle.setText("Groups");
			break;
		case SEARCH:
			tvTitle.setText("Search");
			break;
		}
	}

	private void setEvent() {
		btSend.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				TargetChat currentTargetChat = DataManager.getInstance(
						MainActivity.this).getCurrentTargetChat();

				if (currentTargetChat == null) {
					return;
				}

				String message = etMessage.getText().toString();

				etMessage.setText("");
				if (mDisplayState == MainDisplayState.CHAT_GROUP) {

					if (currentTargetChat.getChatType() != ChatType.CHAT_GROUP) {
						KiraGameLog
								.d("Wrong ChatType, Not in chatgroup, cant send message!");
					}
					final MessageContent msg = new MessageContent(currentUser
							.getUserID());
					msg.setName(currentUser.getName());
					msg.setMsgType(MsgType.TEXT);
					msg.setAvatarID(currentUser.getUserInfo().getAvatarID());
					msg.setContent(TextFilter.getFilterText(MainActivity.this,
							message));// text filter

					GroupMessageContent groupMessageContent = new GroupMessageContent();
					groupMessageContent.setMessageContent(msg);
					groupMessageContent.setFromGroupJID(currentTargetChat
							.getFromID());
					groupMessageContent.setFromGroupName(currentTargetChat
							.getName());
					ChatService.getInstance().sendMessageChatGroup(
							groupMessageContent, onSendGroupMessageListener);
					// lvChat.setSelection(chatPrivateAdapter.getCount() - 1);

				} else if (mDisplayState == MainDisplayState.CHAT_PRIVATE) {

					if (currentTargetChat.getChatType() != ChatType.CHAT_PRIVATE) {
						KiraGameLog
								.d("Wrong ChatType, Not in chatprivate, cant send message!");
					}

					PrivateMessageContent privateMessageContent = new PrivateMessageContent(
							MainActivity.this, message, MsgType.TEXT,
							currentTargetChat);

					sendMessageTextPrivate(privateMessageContent);
				} else {
					return;
				}
			}
		});

		lvChat.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				if (mDisplayState == MainDisplayState.CHAT_PRIVATE) {
					return;
				}
				MessageContent messageContent = (MessageContent) parent
						.getAdapter().getItem(position);
				TargetChat targetChat = new TargetChat(messageContent);
				showChat(targetChat);
			}
		});

		lvChat.setOnScrollListener(new OnScrollListener() {

			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onScroll(AbsListView view, int firstVisibleItem,
					int visibleItemCount, int totalItemCount) {
				if (view.getFirstVisiblePosition() <= 0) {
					if (!canLoadMore) {
						return;
					}
					moreLoadMessage();
				}
			}
		});

		etMessage.setOnFocusChangeListener(new OnFocusChangeListener() {

			@Override
			public void onFocusChange(View v, boolean hasFocus) {
				if (hasFocus) {
					gvEmoticons.setVisibility(View.GONE);
				}
			}
		});

		etMessage.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {

			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {

			}

			@Override
			public void afterTextChanged(Editable s) {
				int lenght = etMessage.getText().toString().trim().length();
				if (lenght > 0) {
					if ((mDisplayState == MainDisplayState.CHAT_PRIVATE)) {
						sendChatTyping();
					}
					btSend.setEnabled(true);
				} else {
					btSend.setEnabled(false);
				}
			}
		});
		gvEmoticons.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				etMessage.append(Emoticons.getSmiledText(MainActivity.this,
						Common.emoticonsName[position]));
			}
		});

		btEmoticon.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (gvEmoticons.getVisibility() == View.GONE
						|| gvEmoticons.getVisibility() == View.INVISIBLE) {
					gvEmoticons.setVisibility(View.VISIBLE);
					Utils.hideKeyboard(MainActivity.this, etMessage);
					lvChat.requestFocus();
				} else {
					gvEmoticons.setVisibility(View.GONE);
					etMessage.requestFocus();
					Utils.showKeyboard(MainActivity.this, etMessage);
				}
			}
		});
		slidingLayout.setPanelSlideListener(new PanelSlideListener() {

			@Override
			public void onPanelSlide(View panel, float slideOffset) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onPanelHidden(View panel) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onPanelExpanded(View panel) {
				changeActionBarState();
			}

			@Override
			public void onPanelCollapsed(View panel) {
				initAdsTimer();
				mDisplayState = MainDisplayState.MAIN;
				changeAdViewLayout();
				Utils.hideKeyboard(MainActivity.this, etMessage);
				changeActionBarState();
				DataManager.getInstance(MainActivity.this)
						.setCurrentTargetChat(null);
				if (mContent == null) {
					return;
				}
				switch (currentMenuItem) {

				case MESSAGE:
					((MessageFragment) mContent).refreshData();
					break;
				default:
					break;
				}
			}

			@Override
			public void onPanelAnchored(View panel) {
				// TODO Auto-generated method stub

			}
		});

		ibAction.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				hideDrawerMenu();
				if (mDisplayState == MainDisplayState.MAIN) {
					switch (currentMenuItem) {
					case MESSAGE:
						showCreateNewChat();
						break;
					case FRIEND:
						showEditProfileFragment();
						break;
					case NEARBY:
						showEditProfileFragment();
						break;
					case SUGGESTED_FRIEND:
						showEditProfileFragment();
						break;
					case PUBLIC_GROUP:
						showAddNewGroup();
						break;
					case SEARCH:
						showEditProfileFragment();
						break;
					default:
						showEditProfileFragment();
						break;
					}
				} else if (mDisplayState == MainDisplayState.CHAT_PRIVATE) {
					showChatPrivateMenu();
				} else if (mDisplayState == MainDisplayState.CHAT_GROUP) {
					showChatRoomMenu();
				}

			}
		});

		rlMenu.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				mDrawerMenu.toggleMenu();
				Utils.hideKeyboard(MainActivity.this, etMessage);
			}
		});

		btImage.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				showChooseImageFragment();
			}
		});

		ibLogout.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				hideDrawerMenu();
				showLogoutDialog();
			}
		});

		ibEditProfile.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				hideDrawerMenu();
				showEditProfileFragment();
				;
			}
		});

		btFindchat.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				findNewRandomFriend();
			}
		});

		btSetting.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				showSettingFragment();
			}
		});

		// mAdViewMain.setAdListener(new AdListener() {
		// @Override
		// public void onAdLoaded() {
		// mAdViewMain.setVisibility(View.VISIBLE);
		// super.onAdLoaded();
		// }
		//
		// @Override
		// public void onAdFailedToLoad(int errorCode) {
		// mAdViewMain.setVisibility(View.GONE);
		// super.onAdFailedToLoad(errorCode);
		// }
		// });

		ibVideoCall.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				sendVideoCallRequest();
			}
		});

		ibRefresh.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (mContent == null) {
					return;
				}
				switch (currentMenuItem) {
				case SUGGESTED_FRIEND:
					((SuggestedFriendsFragment) mContent).refreshData();
					break;
				case NEARBY:
					((NearbyFragment) mContent).refreshData();
					break;
				case FRIEND:
					((FriendsFragment) mContent).refreshData();
					break;
				case PUBLIC_GROUP:
					((GroupsFragment) mContent).refreshData();
					break;
				case MESSAGE:
					((MessageFragment) mContent).refreshData();
					break;
				case SEARCH:
					((SearchFragment) mContent).refreshData();
					break;
				default:
					break;
				}
			}
		});

		btFindFriendSetting.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				showFindFriendSettingFragment();
			}
		});

		// btClearMessage.setOnClickListener(new OnClickListener() {
		//
		// @Override
		// public void onClick(View v) {
		// hideDrawerMenu();
		// showDeleteMessagesFragment();
		// }
		// });

		mDrawerMenu
				.setOnDrawerStateChangeListener(new OnDrawerStateChangeListener() {

					@Override
					public void onDrawerStateChange(int oldState, int newState) {
						if (newState == MenuDrawer.STATE_OPEN) {

						}
					}

					@Override
					public void onDrawerSlide(float openRatio, int offsetPixels) {

					}
				});

		llSuggestedFriend.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				switchContent(MenuItemType.SUGGESTED_FRIEND);
			}
		});

		llMessage.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				switchContent(MenuItemType.MESSAGE);
			}
		});

		llNearby.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				switchContent(MenuItemType.NEARBY);
			}
		});

		llFriend.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				switchContent(MenuItemType.FRIEND);
			}
		});

		llPublicGroup.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				switchContent(MenuItemType.PUBLIC_GROUP);
			}
		});

		llSearch.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				switchContent(MenuItemType.SEARCH);
			}
		});

		llNotice.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				hideNotice();
			}
		});

	}

	// protected void showSearchFriend() {
	// if (mContent == null) {
	// return;
	// }
	// if (currentMenuItem != MenuItemType.FRIEND) {
	// return;
	// }
	// ((FriendsFragment) mContent).showSearchFriend();
	// }

	protected void findNewRandomFriend() {
		findUserIDInList.clear();
		isFindingChat = true;
		findFriendChatWithSetting(1, true);
	}

	private void showCreateNewChat() {
		if (mContent == null) {
			return;
		}
		if (currentMenuItem != MenuItemType.MESSAGE) {
			return;
		}
		((MessageFragment) mContent).createNewChat();
	}

	protected void showAddNewGroup() {
		if (mContent == null) {
			return;
		}
		if (currentMenuItem != MenuItemType.PUBLIC_GROUP) {
			return;
		}
		((GroupsFragment) mContent).addGroup();
	}

	private OnSendPrivateMessageListener onSendPrivateMessageListener = new OnSendPrivateMessageListener() {

		@Override
		public void onSendMessageSuccessed(
				PrivateMessageContent privateMessageContent) {

			MessageContent msg = privateMessageContent.getMessageContent();
			if (msg.getMsgType() == MsgType.IMAGE
					|| msg.getMsgType() == MsgType.TEXT) {
				updateListViewChatState(
						privateMessageContent.getMessageContent(),
						MessageState.SENT);
				updateMessageDBState(privateMessageContent.getMessageContent(),
						MessageState.SENT);
			}

		}

		@Override
		public void onSendMessageFailed(final ErrorCode errorCode,
				final PrivateMessageContent privateMessageContent) {
			runOnUiThread(new Runnable() {
				public void run() {
					updateListViewChatState(
							privateMessageContent.getMessageContent(),
							MessageState.ERROR);
					updateMessageDBState(
							privateMessageContent.getMessageContent(),
							MessageState.ERROR);
					showSendPrivateMessageFailedNotice(errorCode,
							privateMessageContent);
				}
			});

		}

		@Override
		public void onPreSendMessage(PrivateMessageContent privateMessageContent) {
			MessageContent msg = privateMessageContent.getMessageContent();
			if (msg.getMsgType() == MsgType.IMAGE
					|| msg.getMsgType() == MsgType.TEXT) {
				addMessageToDB(privateMessageContent);
				addToListViewChat(privateMessageContent);

			}

		}
	};

	OnSendGroupMessageListener onSendGroupMessageListener = new OnSendGroupMessageListener() {

		@Override
		public void onSendMessageSuccessed(MessageContent messageContent) {

		}

		@Override
		public void onSendMessageFailed(final ErrorCode errorCode,
				final GroupMessageContent groupMessageContent) {
			runOnUiThread(new Runnable() {
				public void run() {
					showSendPrivateMessageFailedNotice(errorCode,
							groupMessageContent);
				}
			});
		}

		@Override
		public void onPreSendMessage() {

		}
	};

	private void clearChatData() {
		messagesData.clear();
		chatAdapter.notifyDataSetChanged();
	}

	protected void updateMessageDBState(MessageContent messageContent,
			MessageState messageState) {
		MessagesDataManager.getInstance(this).updateMessageState(
				messageContent.getMessageID(), messageState);
	}

	protected void addToListViewChat(PrivateMessageContent privateMessageContent) {
		messagesData.add(privateMessageContent.getMessageContent());
		refreshListViewChat();
	}

	protected void addMessageToDB(PrivateMessageContent privateMessageContent) {
		DetailedMessage detailedMessage = new DetailedMessage();
		HistoryMessage historyMessage = new HistoryMessage();
		detailedMessage.setTargetID(privateMessageContent.getTargetUserID());
		detailedMessage
				.setTargetName(privateMessageContent.getTargetUserName());
		detailedMessage.setMessageContent(privateMessageContent
				.getMessageContent());
		historyMessage.setUnreadNum(0);
		historyMessage.setChatType(ChatType.CHAT_PRIVATE);
		historyMessage.setDetailedMessage(detailedMessage);
		MessagesDataManager.getInstance(MainActivity.this).saveMessageDatabase(
				historyMessage);
	}

	protected void updateListViewChatState(MessageContent messageContent,
			MessageState messageState) {
		messageContent.setMessageState(messageState);
		for (MessageContent mMessageContent : messagesData) {
			if ((mMessageContent.getMessageID() != null)
					&& mMessageContent.getMessageID().equals(
							messageContent.getMessageID())) {
				mMessageContent.setMessageState(messageState);
				break;
			}
		}
		refreshListViewChat();
	}

	protected void refreshListViewChat() {
		chatAdapter.notifyDataSetChanged();
		lvChat.setSelection(chatAdapter.getCount() - 1);
		if (messagesData.size() > 0) {
			tvMessageTip.setVisibility(View.GONE);
		}
	}

	protected void showSendPrivateMessageFailedNotice(ErrorCode errorCode,
			final PrivateMessageContent privateMessageContent) {
		switch (errorCode) {
		case CONNECT_SERVER_ERROR:
			showConnectServerError(Error.ErrorInfo[errorCode.ordinal()]);
			break;

		case CAN_NOT_SEND_MESSAGE:
			hideNotice();
			break;
		default:
			break;
		}

	}

	private void showSendPrivateMessageFailedNotice(ErrorCode errorCode,
			final GroupMessageContent groupMessageContent) {
		switch (errorCode) {
		case CONNECT_SERVER_ERROR:
			showConnectServerError(Error.ErrorInfo[errorCode.ordinal()]);
			break;

		case CAN_NOT_SEND_MESSAGE:
			showNotice(false, Error.ErrorInfo[errorCode.ordinal()], "RESEND",
					new OnClickListener() {

						@Override
						public void onClick(View v) {
							ChatService.getInstance().sendMessageChatGroup(
									groupMessageContent,
									onSendGroupMessageListener);
						}
					});
			break;
		case JOIN_ROOM_FAIL:
			showNotice(false, Error.ErrorInfo[errorCode.ordinal()], "REJOIN",
					new OnClickListener() {

						@Override
						public void onClick(View v) {
							ChatService.getInstance().joinroom(
									groupMessageContent.getFromGroupJID(),
									groupMessageContent.getFromGroupName(),
									joinRoomListener);
						}
					});
			break;
		default:
			break;
		}
	}

	OnJoinRoomListener joinRoomListener = new OnJoinRoomListener() {

		@Override
		public void onPreJoinRoom() {
			KiraGameLog.d("onPreJoinRoom");
			runOnUiThread(new Runnable() {
				@Override
				public void run() {
					showOnPreJoinRoomNotice();
				}
			});

		}

		@Override
		public void onJoinRoomSuccessed(final String roomJID,
				final String groupName) {
			KiraGameLog.d("onJoinRoomSuccessed");
			runOnUiThread(new Runnable() {
				@Override
				public void run() {
					doOnJoinRoomSuccessed(roomJID, groupName);
				}
			});

		}

		@Override
		public void onJoinRoomFailed(final ErrorCode errorCode,
				final String roomJID, final String groupName) {
			KiraGameLog.d("onJoinRoomFailed");

			runOnUiThread(new Runnable() {
				@Override
				public void run() {
					showJoinRoomErrorNotice(errorCode, roomJID, groupName);
				}
			});
		}
	};

	private void showJoinRoomErrorNotice(ErrorCode errorCode,
			final String roomJID, final String groupName) {
		switch (errorCode) {
		case CONNECT_SERVER_ERROR:
			showConnectServerError(Error.ErrorInfo[errorCode.ordinal()]);
			break;

		case JOIN_ROOM_FAIL_NOT_MEMBER:
			showNotice(false, Error.ErrorInfo[errorCode.ordinal()], "RETRY",
					new OnClickListener() {

						@Override
						public void onClick(View v) {
							ChatService.getInstance().joinroom(roomJID,
									groupName, joinRoomListener);
						}
					});
			break;

		case JOIN_ROOM_FAIL:
			showNotice(false, Error.ErrorInfo[errorCode.ordinal()], "RETRY",
					new OnClickListener() {

						@Override
						public void onClick(View v) {
							ChatService.getInstance().joinroom(roomJID,
									groupName, joinRoomListener);
						}
					});
			break;

		default:
			break;
		}

	}

	protected void doOnJoinRoomSuccessed(final String roomJID,
			final String groupName) {
		TargetChat targetChat = new TargetChat(ChatType.CHAT_GROUP, roomJID,
				groupName);
		showChat(targetChat);
		hideNotice();
	}

	private void showOnPreJoinRoomNotice() {
		showNotice(true, InfoText.JOINING_GROUP, null, null);
	}

	// //

	protected void showChatRoomMenu() {
		TargetChat currentTargetChat = DataManager.getInstance(
				MainActivity.this).getCurrentTargetChat();
		if (currentTargetChat == null) {
			return;
		}
		final String roomJID = currentTargetChat.getFromID();
		AlertDialog.Builder aBuilder = new AlertDialog.Builder(
				MainActivity.this);
		aBuilder.setItems(new String[] { "Hide", "Add friend to group",
				"Leave group", "Report" }, new Dialog.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				switch (which) {
				case 0:
					hideChat();
					break;
				case 1:
					addFriendToGroup(roomJID);
					break;
				case 2:
					leaveGroup(roomJID);
					break;
				case 3:
					Utils.reportGroup(roomJID);
					break;
				default:
					break;
				}
			}
		});

		AlertDialog alertDialog = aBuilder.create();
		alertDialog.setCanceledOnTouchOutside(true);
		alertDialog.show();
	}

	protected void leaveGroup(String roomJID) {
		hideChat();
		ChatService.getInstance().leaveGroup(roomJID);
		final String groupID = Utils.getDialogIdFromJID(roomJID);
		QBGroupChatManager groupChatManager = QBChatService.getInstance()
				.getGroupChatManager();
		if (groupChatManager == null) {
			return;
		}
		QBRequestUpdateBuilder requestBuilder = new QBRequestUpdateBuilder();
		requestBuilder.pullAll("occupants_ids", currentUser.getUserID());

		QBDialog dialog = new QBDialog(groupID);

		groupChatManager.updateDialog(dialog, requestBuilder,
				new QBEntityCallbackImpl<QBDialog>() {
					@Override
					public void onSuccess(QBDialog dialog, Bundle args) {
						KiraGameLog.d("updateDialog success!");
					}

					@Override
					public void onError(List<String> errors) {
						KiraGameLog.d("updateDialog errors " + errors);
					}
				});
	}

	protected void addFriendToGroup(String roomJID) {
		showChooseFriend(roomJID);
	}

	protected void hideChat() {
		slidingLayout.collapsePanel();
		hideNotice();
	}

	protected void showChatPrivateMenu() {
		TargetChat currentTargetChat = DataManager.getInstance(
				MainActivity.this).getCurrentTargetChat();
		if (currentTargetChat == null) {
			return;
		}
		final String currentChatUserID = currentTargetChat.getFromID();
		final boolean isBlock = DataManager.getInstance(MainActivity.this)
				.getBlockUsers().contains(currentChatUserID);
		String blockMenu;
		if (isBlock) {
			blockMenu = "Unblock this user";
		} else {
			blockMenu = "Block this user";
		}

		AlertDialog.Builder aBuilder = new AlertDialog.Builder(
				MainActivity.this);
		aBuilder.setItems(new String[] { "Hide",
				"Stop chatting and Find new people", "View profile",
				"Add friend", blockMenu, "Report this user" },
				new Dialog.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						switch (which) {
						case 0:
							hideChat();
							break;
						case 1:
							stopChatAndFindNewPeople(Integer
									.parseInt(currentChatUserID));
							break;
						case 2:
							User user = new User();
							user.setUserID(Integer.parseInt(currentChatUserID));
							viewProfile(user, false, true);
							break;
						// case 2:
						// sendVideoCallRequest();
						// break;
						case 3:
							Utils.addFriend(currentChatUserID,
									currentUser.getUserID());
							break;
						case 4:
							if (isBlock) {
								DataManager.getInstance(MainActivity.this)
										.removeBlockUsers(currentChatUserID);
								hideNotice();
							} else {
								DataManager.getInstance(MainActivity.this)
										.addBlockUsers(currentChatUserID);
								hideChat();
							}

							break;
						case 5:
							Utils.reportUser(Integer
									.parseInt(currentChatUserID));
							break;
						default:
							break;
						}
					}
				});

		AlertDialog alertDialog = aBuilder.create();
		alertDialog.setCanceledOnTouchOutside(true);
		alertDialog.show();
	}

	protected void stopChatAndFindNewPeople(Integer targetID) {
		hideChat();
		DataManager.getInstance(this).addChattedUsers(targetID);
		findNewRandomFriend();
	}

	private void sendChatTyping() {
		if (isTyping) {
			return;
		}
		isTyping = true;
		TargetChat currentTargetChat = DataManager.getInstance(
				MainActivity.this).getCurrentTargetChat();
		if (currentTargetChat == null) {
			return;
		}

		PrivateMessageContent privateMessageContent = new PrivateMessageContent(
				MainActivity.this, "", MsgType.SEND_TYPING, currentTargetChat);

		ChatService.getInstance().sendMessagePrivate(privateMessageContent,
				null);

		new CountDownTimer(3000, 1000) {

			@Override
			public void onTick(long millisUntilFinished) {

			}

			@Override
			public void onFinish() {
				sendChatStopTyping();
			}
		}.start();
	}

	private void sendChatStopTyping() {
		isTyping = false;
		TargetChat currentTargetChat = DataManager.getInstance(
				MainActivity.this).getCurrentTargetChat();
		if (currentTargetChat == null) {
			return;
		}
		if (currentTargetChat.getChatType() == ChatType.CHAT_GROUP) {
			return;
		}

		PrivateMessageContent privateMessageContent = new PrivateMessageContent(
				MainActivity.this, "", MsgType.SEND_STOP_TYPING,
				currentTargetChat);

		try {
			ChatService.getInstance().sendMessagePrivate(privateMessageContent,
					null);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void showChat(final TargetChat targetChat) {
		if (targetChat == null) {
			return;
		}
		final String fromID = targetChat.getFromID();
		if (fromID.equals(Integer.toString(currentUser.getUserID()))) {
			return;
		}
		if (mCountDownTimer != null) {
			mCountDownTimer.cancel();
		}
		clearChatData();
		etMessage.setText("");
		resetUnreadMessageNum(fromID);
		DataManager.getInstance(this).setCurrentTargetChat(targetChat);
		tvName.setText(targetChat.getName());
		if (targetChat.getChatType() == ChatType.CHAT_PRIVATE) {
			chatAdapter.setIsChatGroup(false);
			mDisplayState = MainDisplayState.CHAT_PRIVATE;
			sendChatStopTyping();
			btImage.setVisibility(View.VISIBLE);
			final boolean isBlock = DataManager.getInstance(MainActivity.this)
					.getBlockUsers().contains(fromID);
			if (isBlock) {
				showNotice(false, "You blocked this user!", "Unblock",
						new OnClickListener() {

							@Override
							public void onClick(View v) {
								DataManager.getInstance(MainActivity.this)
										.removeBlockUsers(fromID);
								hideNotice();
							}
						});
			} else {
				hideNotice();
			}
			loadNewMessageData(fromID);
		} else if (targetChat.getChatType() == ChatType.CHAT_GROUP) {
			chatAdapter.setIsChatGroup(true);
			mDisplayState = MainDisplayState.CHAT_GROUP;
			btImage.setVisibility(View.GONE);
			loadNewMessageData(fromID);
		}
		changeActionBarState();
		sendCheckOnline(fromID);
		changeAdViewLayout();
		if (slidingLayout != null && !slidingLayout.isPanelExpanded()) {
			slidingLayout.expandPanel();
		}

	}

	private void loadMessage(String fromID, int page) {
		List<MessageContent> messages = new ArrayList<MessageContent>();
		messages.addAll(MessagesDataManager.getInstance(this).getMessages(
				fromID, page, 30));
		messagesData.addAll(0, messages);
		chatAdapter.notifyDataSetChanged();
		lvChat.setSelection(messages.size());
		isLoadDone = true;
		hideLoadMoreView();
		if (messages.size() < 30) {
			canLoadMore = false;
		} else {
			canLoadMore = true;
		}
		if (messagesData.size() == 0
				&& mDisplayState == MainDisplayState.CHAT_PRIVATE) {
			TargetChat currentTargetChat = DataManager.getInstance(
					MainActivity.this).getCurrentTargetChat();
			if (currentTargetChat == null) {
				return;
			}
			String targetName = currentTargetChat.getName();
			tvMessageTip.setVisibility(View.VISIBLE);
			tvMessageTip.setText("You're now chatting with " + targetName
					+ ". Let's say hi!");
		} else {
			tvMessageTip.setVisibility(View.GONE);
		}
	}

	private void loadNewMessageData(String fromID) {
		page = 0;
		isLoadDone = false;
		canLoadMore = false;
		clearChatData();
		loadMessage(fromID, page);
	}

	private void moreLoadMessage() {
		if (!isLoadDone) {
			return;
		}
		final TargetChat currenTargetChat = DataManager.getInstance(this)
				.getCurrentTargetChat();
		if (currenTargetChat == null) {
			return;
		}
		isLoadDone = false;
		page++;

		showLoadMoreView();
		Handler handler = new Handler();
		handler.postDelayed(new Runnable() {
			@Override
			public void run() {
				KiraGameLog.d("load more with page " + page);
				loadMessage(currenTargetChat.getFromID(), page);
			}
		}, 1000);

	}

	private void showLoadMoreView() {
		loadmoreView.setVisibility(View.VISIBLE);
	}

	private void hideLoadMoreView() {
		loadmoreView.setVisibility(View.GONE);
	}

	private void resetUnreadMessageNum(String fromId) {
		MessagesDataManager.getInstance(this).resetHistoryMessageUnreadNum(
				fromId);
		refreshMessageNum();
		if (mContent != null && currentMenuItem == MenuItemType.MESSAGE) {
			((MessageFragment) mContent).refreshData();
		}
	}

	private void sendCheckOnline(String currentChatUserID) {
		if (mDisplayState != MainDisplayState.CHAT_PRIVATE) {
			return;
		}
		// PrivateMessageContent privateMessageContent = new
		// PrivateMessageContent(
		// this, "", MsgType.CHECK_USER_ONLINE, currentChatUserID);
		// try {
		// ChatService.getInstance().sendMessagePrivate(privateMessageContent,
		// false, null);
		// } catch (Exception e) {
		// e.printStackTrace();
		// }
		QBUsers.getUser(Integer.parseInt(currentChatUserID),
				new QBEntityCallbackImpl<QBUser>() {
					@Override
					public void onSuccess(QBUser qbuser, Bundle args) {
						long currentTime = System.currentTimeMillis();
						long userLastRequestAtTime = qbuser.getLastRequestAt()
								.getTime();
						long diff = currentTime - userLastRequestAtTime;
						// if user didn't do anything last 5 minutes (5*60*1000
						// milliseconds)
						if (diff < 3 * 60 * 1000) {
							setOnlineState(true, "");
						} else {
							setOnlineState(false,
									Utils.parseDiffTimeToString(diff));
						}
					}

					@Override
					public void onError(List<String> errors) {

					}
				});
	}

	private void setOnlineState(boolean isOnline, String status) {
		if (isOnline) {
			tvStatus.setText("Online");
			tvStatus.setVisibility(View.VISIBLE);
		} else {
			tvStatus.setText("Last seen " + status);
			tvStatus.setVisibility(View.VISIBLE);
		}
	}

	private BroadcastReceiver changeUIReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			String actionUIMAin = intent
					.getStringExtra(ChatService.CONTROL_ACTION);
			String message = intent.getStringExtra(ChatService.CONTROL_MESSAGE);
			// KiraGameLog.d("get broadcast receive with action " + actionUIMAin
			// + " and message " + message);
			switch (actionUIMAin) {
			case ChatService.MAIN_ACTION_ON_PRE_SETUP_SERVER:
				onPreSetUpServer();
				break;
			case ChatService.MAIN_ACTION_ON_FINISHED_SETUP_SERVER:
				onFinishedSetupServer(message);
				break;
			case ChatService.MAIN_ACTION_ON_PRE_UPDATE_PROFILE:
				onPreUpdateProfile();
				break;
			case ChatService.MAIN_ACTION_ON_FINISHED_UPDATE_PROFILE:
				onFinishedUpdateProfile(message);
				break;
			case ChatService.MAIN_ACTION_ON_PRE_LOG_OUT:
				onPreLogOut();
				break;
			case ChatService.MAIN_ACTION_ON_FINISHED_LOG_OUT:
				onFinishedLogOut(message);
				break;
			case ChatService.MAIN_ACTION_ON_RECEIVED_MESSAGE_GROUP:
				onReceivedMessageGroup(message);
				break;
			case ChatService.MAIN_ACTION_ON_RECEIVED_MESSAGE_PRIVATE:
				onReceivedMessagePrivate(message);
				break;
			case ChatService.MAIN_ACTION_NOTIFY_CONNECTION_ONLINE:
				notifyConnectionOnline();
				break;
			case ChatService.MAIN_ACTION_NOTIFY_CONNECTION_OFFLINE:
				notifyConnectionOffline();
				break;
			default:
				break;
			}
		}
	};

	// CALLBACK FROM CHAT SERVICE

	private void notifyConnectionOffline() {
		KiraGameLog.d("No Internet connection!");
		showNotice(false, "No Internet Connection!", "WIFI SETTING",
				new OnClickListener() {

					@Override
					public void onClick(View v) {
						Intent intent = new Intent(
								Settings.ACTION_WIFI_SETTINGS);
						startActivity(intent);
					}
				});
	}

	protected void onReceivedMessagePrivate(String message) {
		MessageContent messageContent = MessageContent
				.fromJsonToMessageContent(message);
		if (messageContent == null) {
			return;
		}
		String sendFrom = String.valueOf(messageContent.getFromUserID());
		TargetChat currentTargetChat = DataManager.getInstance(this)
				.getCurrentTargetChat();
		String currentChatID = null;
		if (currentTargetChat != null) {
			currentChatID = currentTargetChat.getFromID();
		}

		switch (messageContent.getMsgType()) {
		case SAY_HI_REQUEST:
			receiveSayHiRequest(messageContent);
			break;
		case SEND_TYPING:
			if (currentChatID != null && currentChatID.equals(sendFrom)) {
				showChatTyping(messageContent.getName());
			}
			break;
		case SEND_STOP_TYPING:
			if (currentChatID != null && currentChatID.equals(sendFrom)) {
				hideChatTyping();
			}
			break;
		case CHECK_USER_ONLINE:
			sendUserOnlineStatus(sendFrom);
			break;
		case USER_ONLINE:
			// updateOnlineStatusCurrentChat(sendFrom);
			break;
		case CHECK_FRIEND_ONLINE:
			sendFriendOnlineStatus(sendFrom);
			break;
		case FRIEND_ONLINE:
			if (mContent != null && currentMenuItem == MenuItemType.FRIEND) {
				((FriendsFragment) mContent)
						.updateOnlineStatusFriendList(sendFrom);
			}
			break;
		case ADD_GROUP:
			onReceivedAddGroupNotify(messageContent);
			break;
		case TEXT:
			if (currentChatID != null && currentChatID.equals(sendFrom)) {
				updateListMessageInChat(messageContent);
			} else {
				updateMessageInMessagesFragment();
			}
			break;
		case IMAGE:
			if (currentChatID != null && currentChatID.equals(sendFrom)) {
				updateListMessageInChat(messageContent);
			} else {
				updateMessageInMessagesFragment();
			}
			break;
		case SEND_CHAT_VIDEO_REQUEST:
			messageContent.setMsgType(MsgType.RECEIVE_CHAT_VIDEO_REQUEST);
			String text = messageContent.getName() + " video calling...";
			messageContent.setContent(text);
			if (currentChatID != null && currentChatID.equals(sendFrom)) {
				updateListMessageInChat(messageContent);
			} else {
				updateMessageInMessagesFragment();
			}
			break;
		case ACCEPT_VIDEO_CALL:
			startVideoCallActitity(messageContent.getFromUserID(),
					messageContent.getName());
			if (currentChatID != null && currentChatID.equals(sendFrom)) {
				updateListMessageInChat(messageContent);
			} else {
				updateMessageInMessagesFragment();
			}
			break;
		case REJECT_VIDEO_CALL:
			if (currentChatID != null && currentChatID.equals(sendFrom)) {
				updateListMessageInChat(messageContent);
			} else {
				updateMessageInMessagesFragment();
			}
			break;
		case MESSAGE_STATE_DILIVER:
			MessageContent msgContent = MessageContent
					.fromJsonToMessageContent(messageContent.getContent());
			if (msgContent != null) {
				updateListViewChatState(msgContent, MessageState.DELIVERED);
				updateMessageDBState(msgContent, MessageState.DELIVERED);
			}
			break;
		default:
			break;
		}
	}

	protected void startVideoCallActitity(Integer targetID, String name) {
		Intent intent = new Intent(this, VideoCallActivity.class);
		intent.putExtra(Common.ExtraKey.USER_ID, targetID);
		intent.putExtra(Common.ExtraKey.USER_NAME, name);
		intent.putExtra(Common.ExtraKey.IS_CALLER, true);
		startActivity(intent);
	}

	private void sendVideoCallRequest() {
		Toast.makeText(this, "This feature is coming soon in next version...",
				Toast.LENGTH_LONG).show();

		// TargetChat currentTargetChat = DataManager.getInstance(
		// MainActivity.this).getCurrentTargetChat();
		//
		// if (currentTargetChat == null) {
		// return;
		// }
		// String message = "Video calling to " + currentTargetChat.getName()
		// + "...";
		//
		// PrivateMessageContent privateMessageContent = new
		// PrivateMessageContent(
		// MainActivity.this, message, MsgType.SEND_CHAT_VIDEO_REQUEST,
		// currentTargetChat);
		// ChatService.getInstance().sendMessagePrivate(privateMessageContent,
		// true, onSendPrivateMessageListener);
	}

	private void onReceivedAddGroupNotify(MessageContent messageContent) {
		GroupChat groupChat = GroupChat.fromJsonToGroupChat(messageContent
				.getContent());
		ChatService.getInstance().joinroom(groupChat.getGroupJID(),
				groupChat.getName(), null);
	}

	protected void onReceivedMessageGroup(String message) {
		GroupMessageContent groupMessageContent = GroupMessageContent
				.fromJsonToGroupMessageContent(message);
		if (groupMessageContent == null) {
			return;
		}
		MessageContent messageContent = groupMessageContent.getMessageContent();
		if (messageContent == null) {
			return;
		}
		switch (messageContent.getMsgType()) {
		case TEXT:
			displayMessage(groupMessageContent);
			break;
		case IMAGE:
			displayMessage(groupMessageContent);
			break;
		case UPDATE_GROUP_INFO:
			displayMessage(groupMessageContent);
			break;
		default:
			break;
		}

	}

	private void displayMessage(GroupMessageContent groupMessageContent) {
		TargetChat currentTargetChat = DataManager.getInstance(this)
				.getCurrentTargetChat();
		if (currentTargetChat == null) {
			updateMessageInMessagesFragment();
			return;
		}

		String currentChatID = currentTargetChat.getFromID();
		if (currentChatID != null
				&& currentChatID.equals(groupMessageContent.getFromGroupJID())) {
			updateListMessageInChat(groupMessageContent.getMessageContent());
		} else {
			updateMessageInMessagesFragment();
		}
	}

	protected void updateMessageInMessagesFragment() {
		if (mContent != null && currentMenuItem == MenuItemType.MESSAGE) {
			((MessageFragment) mContent).refreshData();
		}
		// Update message num in menu
		messageNum++;
		updateMessageNum();
	}

	private void updateMessageNum() {
		if (messageNum == 0) {
			tvMessageNum.setText("");
			tvNumMessage.setText("");
			tvMessageNum.setVisibility(View.GONE);
			tvNumMessage.setVisibility(View.GONE);
		} else {
			if (messageNum > 9) {
				tvMessageNum.setText("9+");
				tvNumMessage.setText("9+");
			} else {
				tvMessageNum.setText(String.valueOf(messageNum));
				tvNumMessage.setText(String.valueOf(messageNum));
			}
			tvMessageNum.setVisibility(View.VISIBLE);
			tvNumMessage.setVisibility(View.VISIBLE);
		}
	}

	public void refreshMessageNum() {
		messageNum = MessagesDataManager.getInstance(this)
				.getTotalMessageNumUnread();
		updateMessageNum();
	}

	private void notifyConnectionOnline() {
		KiraGameLog.d("Internet connection successful!");
		hideNotice();
	}

	private void receiveSayHiRequest(MessageContent messageContent) {
		if (messageContent == null) {
			return;
		}
		Set<Integer> chattedUsers = DataManager.getInstance(this)
				.getChattedUsers();
		if (chattedUsers.contains(messageContent.getFromUserID())) {
			return;
		}

		KiraGameLog.d("receiveSayHiRequest from " + messageContent.toJson());

		User fromUser = null;
		try {
			fromUser = User.fromJsonToUser(messageContent.getContent());
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (fromUser == null) {
			return;
		}
		GenderType searchGender = DataManager.getInstance(this)
				.getGenderSearch();

		if (isFindingChat) {
			if (searchGender == GenderType.ANY
					|| (searchGender == fromUser.getUserInfo().getGender())) {
				TargetChat targetChat = new TargetChat(messageContent);
				showChat(targetChat);
				DataManager.getInstance(this).addChattedUsers(
						messageContent.getFromUserID());
				isFindingChat = false;
				hideNotice();
				PrivateMessageContent privateMessageContent = new PrivateMessageContent(
						this, currentUser.toJson(), MsgType.SAY_HI_REQUEST,
						targetChat);
				ChatService.getInstance().sendMessagePrivate(
						privateMessageContent, null);
			}
		}
	}

	// private void onPreJoinRoom() {
	// showNotice(true, "Joining room...", null, null);
	// messageContentRoomData.clear();
	// chatRoomAdapter.notifyDataSetChanged();
	// // Update new message num in message fragment
	// // updateNewMessagesNum();
	// changeActionBarState(mDisplayState);
	// }

	protected void onPreSetUpServer() {
		showNotice(true, "Connecting to server...", null, null);
	}

	protected void onFinishedSetupServer(String error) {
		hideNotice();
		if (error != null) {
			// ERROR
			showNotice(false, error, "RETRY", new OnClickListener() {

				@Override
				public void onClick(View v) {
					hideNotice();
					ChatService.getInstance().setUpServer();
				}
			});
		}
	}

	private void onFinishedUpdateProfile(String error) {
		hideNotice();
		if (error != null) {
			// ERROR
			showNotice(false, error, "RETRY", new OnClickListener() {

				@Override
				public void onClick(View v) {
					hideNotice();
					showEditProfileFragment();
				}
			});
			// update profile fail. try again?
		} else {
			currentUser = DataManager.getInstance(this).getCurrentUser();
		}
	}

	private void onPreUpdateProfile() {
		showNotice(true, "Updating profile...", null, null);
	}

	private void onPreLogOut() {
		showNotice(true, "Logout...", null, null);
	}

	private void onFinishedLogOut(String error) {
		hideNotice();
	}

	// ROOM

	// public void updateListUserInRoom(String message) {
	// if (message != null) {
	// userData.addAll(User.fromJsonArrayToUsers(message));
	// }
	// userAdapter.notifyDataSetChanged();
	// }

	// public void onUserEnteredRoom(User mUser) {
	// if (!currentUserIDsInList.contains(mUser.getUserID())) {
	// currentUserIDsInList.add(mUser.getUserID());
	// List<User> users = new ArrayList<User>();
	// users.add(mUser);
	// updateListUserInRoom(User.toJsonArray(users));
	// }
	//
	// }
	//
	// public void onUserLeftRoom(Integer id) {
	// if (currentUserIDsInList.contains(id)) {
	// currentUserIDsInList.remove(id);
	// Iterator<User> user = userData.iterator();
	// while (user.hasNext()) {
	// User mUser = (User) user.next();
	// if (id.equals(mUser.getUserID())) {
	// user.remove();
	// break;
	// }
	// }
	// userAdapter.notifyDataSetChanged();
	// }
	//
	// }

	// private void updateInfoInRoom() {
	// // Send message update room to user in room
	// ChatService.getInstance().sendMessageChatRoom(
	// DataManager.getInstance(this).getUser().toJson(),
	// MsgType.UPDATE_INFO);
	// }

	// private void updateUserInfoInRoomStatus(User userInfoUpdated) {
	// for (User user : userData) {
	// if (user.getUserID().equals(userInfoUpdated.getUserID())) {
	// user.setName(userInfoUpdated.getName());
	// UserInfo userInfo = new UserInfo();
	// userInfo.setStatus(userInfoUpdated.getUserInfo().getStatus());
	// userInfo.setGender(userInfoUpdated.getUserInfo().getGender());
	// user.setUserInfo(userInfo);
	// break;
	// }
	// }
	// userAdapter.notifyDataSetChanged();
	// }

	// MENU FRAGMENT
	private View getMenuView() {
		View view = getLayoutInflater().inflate(R.layout.fragment_menu, null);
		findViewIdsMenuFragment(view);
		initMenuFragment();
		return view;
	}

	private void initMenuFragment() {

	}

	private void findViewIdsMenuFragment(View view) {
		llMessage = (LinearLayout) view.findViewById(R.id.ll_message);
		tvMessageNum = (TextView) view.findViewById(R.id.tv_message_num);
		llFriend = (LinearLayout) view.findViewById(R.id.ll_friend);
		llNearby = (LinearLayout) view.findViewById(R.id.ll_nearby);
		llSuggestedFriend = (LinearLayout) view
				.findViewById(R.id.ll_suggested_friend);
		llPublicGroup = (LinearLayout) view.findViewById(R.id.ll_public_group);
		llSearch = (LinearLayout) view.findViewById(R.id.ll_search);
		ibLogout = (ImageButton) view.findViewById(R.id.ib_logout);
		ibEditProfile = (ImageButton) view.findViewById(R.id.ib_edit_profile);
		btSetting = (Button) view.findViewById(R.id.bt_setting);
	}

	// CHAT PRIVATE
	private void updateListMessageInChat(MessageContent messageContent) {
		if (messageContent == null) {
			return;
		}
		Integer fromUserID = messageContent.getFromUserID();

		hideChatTyping();
		messagesData.add(messageContent);
		refreshListViewChat();

		if (!fromUserID.equals(currentUser.getUserID())) {
			if (DataManager.getInstance(this).getVibrationSetting()) {
				long[] pattern = { 0, 100 };
				vibrator.vibrate(pattern, -1);
			}
		}

	}

	private void sendFriendOnlineStatus(String fromUserID) {
		PrivateMessageContent privateMessageContent = new PrivateMessageContent(
				MainActivity.this, "", MsgType.FRIEND_ONLINE, fromUserID);

		ChatService.getInstance().sendMessagePrivate(privateMessageContent,
				null);
	}

	// private void updateOnlineStatusCurrentChat(String fromUserID) {
	// TargetChat currentTargetChat = DataManager.getInstance(
	// MainActivity.this).getCurrentTargetChat();
	// if (currentTargetChat == null) {
	// return;
	// }
	// String currentChatUserID = currentTargetChat.getFromID();
	// if (fromUserID.equals(currentChatUserID)) {
	// setOnlineState(true);
	// }
	// }

	private void sendUserOnlineStatus(String fromUserID) {
		PrivateMessageContent privateMessageContent = new PrivateMessageContent(
				MainActivity.this, "", MsgType.USER_ONLINE, fromUserID);

		ChatService.getInstance().sendMessagePrivate(privateMessageContent,
				null);
	}

	private void hideChatTyping() {
		tvTyping.setVisibility(View.GONE);
	}

	private void showChatTyping(String fromUserName) {
		tvTyping.setVisibility(View.VISIBLE);
		tvTyping.setText(fromUserName + " is typing...");
	}

	private void findFriendChatWithSetting(int page, boolean isShowNotice) {
		hideDrawerMenu();
		if (!isFindingChat) {
			return;
		}

		if (isShowNotice) {
			showNotice(true, "Finding random chat...", "Cancel",
					new OnClickListener() {

						@Override
						public void onClick(View v) {
							isFindingChat = false;
							hideNotice();
						}
					});
		}

		GenderType genderSearch = DataManager.getInstance(this)
				.getGenderSearch();
		ArrayList<String> userTags = new ArrayList<String>();
		userTags.add(ChatService.ONLINE);
		// userTags.add(ChatService.USER);
		if (genderSearch == GenderType.FEMALE) {
			userTags.add(UserInfo.genderText[GenderType.FEMALE.ordinal()]);
		} else if (genderSearch == GenderType.MALE) {
			userTags.add(UserInfo.genderText[GenderType.MALE.ordinal()]);
		}

		QBPagedRequestBuilder pagedRequestBuilder = new QBPagedRequestBuilder();
		pagedRequestBuilder.setPage(page);
		pagedRequestBuilder.setPerPage(100);
		final Integer currentUserID = currentUser.getUserID();
		final Set<Integer> chattedUsers = DataManager.getInstance(this)
				.getChattedUsers();
		QBUsers.getUsersByTags(userTags, pagedRequestBuilder,
				new QBEntityCallbackImpl<ArrayList<QBUser>>() {

					@Override
					public void onSuccess(ArrayList<QBUser> users, Bundle params) {
						if (users == null || users.size() == 0) {
						} else {
							Collections.shuffle(users);
							for (QBUser qbUser : users) {
								Integer userID = qbUser.getId();
								if (Utils.isOnline(qbUser)
										&& !userID.equals(currentUserID)
										&& !findUserIDInList.contains(userID)
										&& !chattedUsers.contains(userID)) {
									findUserIDInList.add(qbUser.getId());
									KiraGameLog.d("send hi request to "
											+ qbUser);
									PrivateMessageContent privateMessageContent = new PrivateMessageContent(
											MainActivity.this, currentUser
													.toJson(),
											MsgType.SAY_HI_REQUEST, Integer
													.toString(qbUser.getId()));

									ChatService
											.getInstance()
											.sendMessagePrivate(
													privateMessageContent, null);
								}
							}

							int currentPage = params.getInt(Consts.CURR_PAGE);
							int perPage = params.getInt(Consts.PER_PAGE);
							int totalPage = (params
									.getInt(Consts.TOTAL_ENTRIES) / perPage) + 1;

							if (currentPage < totalPage) {
								findFriendChatWithSetting(currentPage + 1,
										false);
								return;
							} else {
								if (isFindingChat) {
									new CountDownTimer(1000 * 30, 1000) {
										@Override
										public void onTick(
												long millisUntilFinished) {
											if (!isFindingChat) {
												this.cancel();
											}
										}

										@Override
										public void onFinish() {
											findFriendChatLv2();
										}
									}.start();
								}
							}
						}

					}

					@Override
					public void onError(List<String> errors) {
						// handleErrors(errors);
						KiraGameLog.d("findFriendChatWithSetting error "
								+ errors);
						findFriendChatLv2();
					}
				});
	}

	protected void findFriendChatLv2() {
		if (findUserIDInList.size() == 0) {
			isFindingChat = false;
			hideNotice();
			return;
		}
		List<Integer> userSeachLv2 = new ArrayList<Integer>();
		userSeachLv2.addAll(findUserIDInList);
		Collections.shuffle(userSeachLv2);
		if (userSeachLv2.size() > 20) {
			userSeachLv2 = userSeachLv2.subList(0, 20);
		}
		QBPagedRequestBuilder pagedRequestBuilder = new QBPagedRequestBuilder();
		pagedRequestBuilder.setPage(1);
		pagedRequestBuilder.setPerPage(20);

		QBUsers.getUsersByIDs(userSeachLv2, pagedRequestBuilder,
				new QBEntityCallbackImpl<ArrayList<QBUser>>() {
					@Override
					public void onSuccess(ArrayList<QBUser> users, Bundle params) {
						List<User> xchatUsers = new ArrayList<User>();
						for (QBUser user : users) {
							if (user.getTags().contains(ChatService.VISIBLE)) {
								xchatUsers.add(Utils.convertQBUserToUser(user));
							}
						}
						if (isFindingChat) {
							showFindFriendResultsFragment(xchatUsers);
						}
						isFindingChat = false;
						hideNotice();
					}

					@Override
					public void onError(List<String> errors) {
						KiraGameLog.d("Get user by ids error: " + errors);
						isFindingChat = false;
						hideNotice();
					}

				});
	}

	private void hideDrawerMenu() {
		if (mDrawerMenu.isMenuVisible()) {
			mDrawerMenu.toggleMenu();
		}
	}

	private void sendImageChat(PrivateMessageContent privateMessageContent) {

		if (mDisplayState == MainDisplayState.CHAT_GROUP) {
			return;
		} else if (mDisplayState == MainDisplayState.CHAT_PRIVATE) {
			ChatService.getInstance().sendMessagePrivate(privateMessageContent,
					null);
		} else {
			return;
		}

	}

	public void showNotice(boolean isShowProgessbar, String message,
			String action, OnClickListener listener) {
		if (isShowProgessbar) {
			pbLoading.setVisibility(View.VISIBLE);
		} else {
			pbLoading.setVisibility(View.GONE);
		}
		if (message != null) {
			tvNotice.setText(message);
		}
		if (action != null) {
			tvAction.setText(action);
			tvAction.setVisibility(View.VISIBLE);
			vSplit.setVisibility(View.VISIBLE);
		} else {
			tvAction.setVisibility(View.GONE);
			vSplit.setVisibility(View.GONE);
		}
		tvAction.setOnClickListener(listener);
		llNotice.setVisibility(View.VISIBLE);
		llNotice.startAnimation(animationShow);
	}

	public void hideNotice() {
		if (llNotice.getVisibility() == View.GONE) {
			return;
		}
		animationHide.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation animation) {
			}

			@Override
			public void onAnimationRepeat(Animation animation) {
			}

			@Override
			public void onAnimationEnd(Animation animation) {
				llNotice.setVisibility(View.GONE);
			}
		});
		llNotice.startAnimation(animationHide);
	}

	private void showEditProfileFragment() {
		try {
			final EditProfileDialogFragment dialog = new EditProfileDialogFragment();
			FragmentTransaction transaction = getSupportFragmentManager()
					.beginTransaction();
			transaction.add(dialog, "EditProfileDialogFragment");
			transaction.commitAllowingStateLoss();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private void showSettingFragment() {
		try {
			hideDrawerMenu();
			final SettingDialogFragment dialog = new SettingDialogFragment();
			dialog.setOnSettingDialogFragment(new OnSettingDialogFragment() {

				@Override
				public void onDontShowSettingChange(boolean mIsInvisible) {
					boolean isInvisible = DataManager.getInstance(
							MainActivity.this).getInvisibleSetting();
					ChatService.getInstance().updateProfile(true, isInvisible);
				}
			});
			FragmentTransaction transaction = getSupportFragmentManager()
					.beginTransaction();
			transaction.add(dialog, "SettingDialogFragment");
			transaction.commitAllowingStateLoss();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private void showChooseImageFragment() {
		try {
			final ChooseImageDialogFragment dialog = new ChooseImageDialogFragment();
			dialog.setOnChooseImageDialogFragment(new OnChooseImageDialogFragment() {

				@Override
				public void onGallery() {
					selectImageFromGallery();
				}

				@Override
				public void onCamera() {
					selectImageFromCamera();
				}
			});
			FragmentTransaction transaction = getSupportFragmentManager()
					.beginTransaction();
			transaction.add(dialog, "ChooseImageDialogFragment");
			transaction.commitAllowingStateLoss();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private void selectImageFromGallery() {
		Intent intent = new Intent(this, ProcessImage.class);
		intent.putExtra(ProcessImage.IS_SELECT_IMAGE_FROM_CAMERA, false);
		intent.putExtra(ProcessImage.ASPECT_RATIO_X, 0);
		intent.putExtra(ProcessImage.ASPECT_RATIO_Y, 0);
		startActivityForResult(intent, Common.RequestCode.CHAT_IMAGE);
	}

	private void selectImageFromCamera() {
		Intent intent = new Intent(this, ProcessImage.class);
		intent.putExtra(ProcessImage.IS_SELECT_IMAGE_FROM_CAMERA, true);
		intent.putExtra(ProcessImage.ASPECT_RATIO_X, 0);
		intent.putExtra(ProcessImage.ASPECT_RATIO_Y, 0);
		startActivityForResult(intent, Common.RequestCode.CHAT_IMAGE);
	}

	private void showFindFriendSettingFragment() {
		try {
			final FindFriendSettingDialogFragment dialog = new FindFriendSettingDialogFragment();
			FragmentTransaction transaction = getSupportFragmentManager()
					.beginTransaction();
			transaction.add(dialog, "FindFriendSettingDialogFragment");
			transaction.commitAllowingStateLoss();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void viewProfile(User user, boolean isShowSendMsg,
			boolean isLoadFromServer) {
		try {
			final ViewProfileFragment dialog = ViewProfileFragment.newInstance(
					user, isShowSendMsg, isLoadFromServer);
			FragmentTransaction transaction = getSupportFragmentManager()
					.beginTransaction();
			transaction.add(dialog, "ViewProfileFragment");
			transaction.commitAllowingStateLoss();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void showFindFriendResultsFragment(List<User> users) {

		try {
			if (users.size() == 0) {
				return;
			}
			final FindFriendResultsFragment dialog = FindFriendResultsFragment
					.newInstance(users);
			FragmentTransaction transaction = getSupportFragmentManager()
					.beginTransaction();
			transaction.add(dialog, "FindFriendResultsFragment");
			transaction.commitAllowingStateLoss();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private void showLogoutDialog() {
		try {
			final LogoutConfirmDialogFragment dialog = new LogoutConfirmDialogFragment();
			dialog.setCancelable(false);
			dialog.setOnExitDialogListener(new OnLogoutDialogListener() {

				@Override
				public void onExit() {
					DataManager.getInstance(MainActivity.this).setIsShowPost(
							false);
					DataManager.getInstance(MainActivity.this)
							.setIsLogout(true);
					Utils.callFacebookLogout(MainActivity.this);
					ChatService.getInstance().logOut();
					finish();
				}

				@Override
				public void onCancel() {

				}
			});
			FragmentTransaction transaction = getSupportFragmentManager()
					.beginTransaction();
			transaction.add(dialog, "LogoutConfirmDialogFragment");
			transaction.commitAllowingStateLoss();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private void showSayHi() {
		try {
			final SayHiDialogFragment dialog = new SayHiDialogFragment();
			dialog.setCancelable(false);
			FragmentTransaction transaction = getSupportFragmentManager()
					.beginTransaction();
			transaction.add(dialog, "SayHiDialogFragment");
			transaction.commitAllowingStateLoss();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private void showChooseFriend(final String roomJID) {
		try {
			final ChooseFriendDialogFragment dialog = ChooseFriendDialogFragment
					.newInstance(roomJID, null);
			dialog.setOnChooseFriendDialogFragment(new OnChooseFriendDialogFragment() {

				@Override
				public void onChooseFriend(final List<SelectFriend> users) {
					if (users.size() == 0) {
						return;
					}
					KiraGameLog.d("list choose friend " + users);
					final List<String> userIDs = new ArrayList<String>();
					final List<String> userNames = new ArrayList<String>();
					for (SelectFriend user : users) {
						userIDs.add(user.getUserID());
						userNames.add(user.getUserName());
					}
					final String groupID = Utils.getDialogIdFromJID(roomJID);
					QBGroupChatManager groupChatManager = QBChatService
							.getInstance().getGroupChatManager();
					if (groupChatManager == null) {
						return;
					}
					QBRequestUpdateBuilder requestBuilder = new QBRequestUpdateBuilder();
					requestBuilder.push("occupants_ids",
							TextUtils.join(",", userIDs));
					QBDialog dialog = new QBDialog(groupID);

					groupChatManager.updateDialog(dialog, requestBuilder,
							new QBEntityCallbackImpl<QBDialog>() {
								@Override
								public void onSuccess(QBDialog dialog,
										Bundle args) {
									KiraGameLog.d("updateDialog success!");
									notifyFriendJoinGroup(dialog, userIDs);
									sendJoinGroupMessageToGroup(dialog,
											userNames);
								}

								@Override
								public void onError(List<String> errors) {
									KiraGameLog.d("updateDialog errors "
											+ errors);
								}
							});
				}

				@Override
				public void onCancel() {

				}
			});
			FragmentTransaction transaction = getSupportFragmentManager()
					.beginTransaction();
			transaction.add(dialog, "ChooseFriendDialogFragment");
			transaction.commitAllowingStateLoss();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private void sendJoinGroupMessageToGroup(QBDialog dialog,
			List<String> userNames) {
		String currentUserName = currentUser.getName();
		MessageContent msg = new MessageContent(currentUser.getUserID());
		msg.setName(currentUserName);
		String content = currentUserName + " add "
				+ TextUtils.join(", ", userNames) + " to group";
		msg.setContent(content);
		msg.setMsgType(MsgType.UPDATE_GROUP_INFO);

		GroupMessageContent groupMessageContent = new GroupMessageContent();
		groupMessageContent.setMessageContent(msg);
		groupMessageContent.setFromGroupJID(dialog.getRoomJid());
		groupMessageContent.setFromGroupName(dialog.getName());
		ChatService.getInstance().sendMessageChatGroup(groupMessageContent,
				null);
	}

	private void notifyFriendJoinGroup(QBDialog qbDialog, List<String> userIDs) {
		GroupChat groupChat = new GroupChat();
		groupChat.setName(qbDialog.getName());
		groupChat.setGroupJID(qbDialog.getRoomJid());
		for (String userID : userIDs) {
			PrivateMessageContent privateMessageContent = new PrivateMessageContent(
					MainActivity.this, groupChat.toJson(), MsgType.ADD_GROUP,
					userID);

			ChatService.getInstance().sendMessagePrivate(privateMessageContent,
					null);

		}
	}

	private Fragment getFragment(MenuItemType menuItemType) {
		switch (menuItemType) {
		case MESSAGE:
			tvTitle.setText("Messages");
			return MessageFragment.newInstance();
		case FRIEND:
			tvTitle.setText("Friends");
			return FriendsFragment.newInstance();
		case NEARBY:
			tvTitle.setText("Nearby");
			return NearbyFragment.newInstance();
		case SUGGESTED_FRIEND:
			tvTitle.setText("Online User");
			return SuggestedFriendsFragment.newInstance();
		case PUBLIC_GROUP:
			tvTitle.setText("Groups");
			return GroupsFragment.newInstance();
		case SEARCH:
			tvTitle.setText("Search");
			return SearchFragment.newInstance();
		}
		return MessageFragment.newInstance();
	}

	private void switchContent(Fragment fragment) {
		mContent = fragment;
		fm.beginTransaction().replace(R.id.content_frame, fragment).commit();
		changeActionBarState();
	}

	private void switchContent(MenuItemType menuItemType) {
		hideChat();
		hideNotice();
		hideInfo();
		hideDrawerMenu();
		stopRefeshAnimation();
		if (currentMenuItem == menuItemType) {
			return;
		}
		currentMenuItem = menuItemType;
		mContent = getFragment(menuItemType);
		fm.beginTransaction().replace(R.id.content_frame, mContent).commit();
		changeActionBarState();
	}

	public void startRefeshAnimation() {
		ibRefresh.startAnimation(animationRotate);
		ibRefresh.setEnabled(false);
	}

	public void stopRefeshAnimation() {
		ibRefresh.clearAnimation();
		ibRefresh.setEnabled(true);
	}

	// COMMON ERROR
	public void showConnectServerError(String errorInfo) {
		showNotice(false, errorInfo, "RECONECT", new OnClickListener() {

			@Override
			public void onClick(View v) {
				ChatService.getInstance().setUpServer();
			}
		});
	}

	public void uploadImageToSever(
			final PrivateMessageContent privateMessageContent) {
		// tai sao hinh nen lon hon hinh goc
		KiraGameLog.d("upload image to sever");
		File file = new File(privateMessageContent.getMessageContent()
				.getContent());
		QBContent.uploadFileTask(file, true, null,
				new QBEntityCallbackImpl<QBFile>() {

					@Override
					public void onSuccess(QBFile updatedFile, Bundle params) {
						String publicUrl = updatedFile.getPublicUrl();
						KiraGameLog.d("upload file success link file "
								+ publicUrl);
						privateMessageContent.getMessageContent().setContent(
								publicUrl);
						sendImageChat(privateMessageContent);
						updateListViewChatState(
								privateMessageContent.getMessageContent(),
								MessageState.SENT);
						updateMessageDBState(
								privateMessageContent.getMessageContent(),
								MessageState.SENT);
					}

					@Override
					public void onError(List<String> errors) {
						KiraGameLog.d("upload file failed! " + errors);
						// finishAndCallBack(null, null);
						updateListViewChatState(
								privateMessageContent.getMessageContent(),
								MessageState.ERROR);
						updateMessageDBState(
								privateMessageContent.getMessageContent(),
								MessageState.ERROR);
					}
				});
	}

	public void sendMessageTextPrivate(
			PrivateMessageContent privateMessageContent) {
		ChatService.getInstance().sendMessagePrivate(privateMessageContent,
				onSendPrivateMessageListener);
	}

	public void sendMessageImagePrivate(String filePath) {
		// show add to database

		TargetChat currentTargetChat = DataManager.getInstance(
				MainActivity.this).getCurrentTargetChat();
		if (currentTargetChat == null) {
			return;
		}

		PrivateMessageContent privateMessageContent = new PrivateMessageContent(
				MainActivity.this, filePath, MsgType.IMAGE, currentTargetChat);

		addMessageToDB(privateMessageContent);
		addToListViewChat(privateMessageContent);

		uploadImageToSever(privateMessageContent);
	}

	public void sendMessageImagePrivate(
			PrivateMessageContent privateMessageContent) {
		addMessageToDB(privateMessageContent);
		addToListViewChat(privateMessageContent);
		if (privateMessageContent.getMessageContent().getContent()
				.contains("http")) {
			sendImageChat(privateMessageContent);
			updateListViewChatState(privateMessageContent.getMessageContent(),
					MessageState.SENT);
			updateMessageDBState(privateMessageContent.getMessageContent(),
					MessageState.SENT);
		} else {
			uploadImageToSever(privateMessageContent);
		}

	}
}
